package com.tanhua.server.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.commons.aliyun.utils.AliyunOssUtils;
import com.tanhua.commons.aliyun.utils.AliyunSmsUtils;
import com.tanhua.commons.baidu.utils.AipUtils;
import com.tanhua.commons.jwt.JwtUtils;
import com.tanhua.commons.utils.FileUtils;
import com.tanhua.commons.vo.ErrorResult;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.dubbo.server.api.UserApi;
import com.tanhua.dubbo.server.api.UserInfoApi;
import com.tanhua.server.interceptor.UserThreadLocal;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserService {

    @Autowired
    private AliyunSmsUtils smsUtils;

    @Autowired
    private AipUtils aipUtils;

    @Autowired
    private AliyunOssUtils ossUtils;

    @Value("jwt.secret")
    private String secret;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference(version = "1.0.0")
    private UserApi userApi;

    @Reference
    private UserInfoApi userInfoApi;

    public static final String REDIS_KEY_PREFIX = "CHECK_CODE_";


    //发送短信验证码
    public ResponseEntity<Object> sendCheckCode(String phone) {
        String redisKey = REDIS_KEY_PREFIX + phone;
        Boolean aBoolean = this.redisTemplate.hasKey(redisKey);
        if(aBoolean) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorResult.duplicate());
        }
        String code = "123456";
        //smsUtils.sendSms(phone,code);
        this.redisTemplate.opsForValue().set(redisKey, code, Duration.ofSeconds(30));
        return ResponseEntity.ok().build();
    }

    //用户登录校验
    public ResponseEntity<Object> login(String phone,String code) {

        if(!this.checkCode(phone, code)) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ErrorResult.loginError());
        }

        User user = userApi.findByMobile(phone);

        Map map = new HashMap();

        map.put("isNew", false);

        if(user == null) {
            user = new User(null,phone, DigestUtils.md5Hex("123456"));
            Long userId = this.userApi.insert(user);
            user.setId(userId);
            map.put("isNew", true);
        }

        String token = JwtUtils.createToken(phone, user.getId(), secret);

        String redisTokenKey = "TOKEN_" + token;

        String redisTokeyValue = JSON.toJSONString(user);

        this.redisTemplate.opsForValue().set(redisTokenKey, redisTokeyValue, Duration.ofHours(1));

        map.put("token", token);

        return ResponseEntity.ok(map);
    }

    /**
     * 完善个人信息
     */
    public ResponseEntity<Object> saveUserInfo(UserInfo userInfo) {
        userInfoApi.save(userInfo);
        return ResponseEntity.ok(null);
    }

    /**
     * 上传头像
     */
    public ResponseEntity<Object> saveLogo(MultipartFile headPhoto,User user) throws IOException {

        if(!aipUtils.detect(headPhoto.getBytes())) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorResult.faceError());
        }

        String filePath = FileUtils.getFilePath(headPhoto.getOriginalFilename());

        String imageUrl = ossUtils.upload(filePath, headPhoto.getInputStream());

        UserInfo info = new UserInfo();

        info.setId(user.getId());

        info.setAvatar(imageUrl);

        userInfoApi.update(info);

        return ResponseEntity.ok(null);
    }

    public boolean checkCode(String phone,String code) {

        String redisKey = REDIS_KEY_PREFIX + phone;

        String value = this.redisTemplate.opsForValue().get(redisKey);

        if(StringUtils.isEmpty(value) || !StringUtils.equals(value, code)){
            return false;
        }

        this.redisTemplate.delete(redisKey);
        return true;
    }

    /**
     * 根据token查询用户数据
     */
    public User queryUserByToken(String token) {
        String redisTokenKey = "TOKEN_" + token;
        String cacheData = this.redisTemplate.opsForValue().get(redisTokenKey);
        if(StringUtils.isEmpty(cacheData)) {
            return null;
        }
        // 刷新时间
        this.redisTemplate.expire(redisTokenKey, 1, TimeUnit.HOURS);
        return JSON.parseObject(cacheData, User.class);
    }


    public ResponseEntity<Void> saveNewMobile(User user){
        userApi.update(user);
        return ResponseEntity.ok(null);
    }

}
